from utils.relations import Many
from utils.prettyrepr import prettify_class


@prettify_class
class Tile(object):
    __slots__ = ("maze", "x", "y", "cx", "cy", "terrain", "all_entities", "active_entities")

    def __init__(self, maze, x, y, terrain=None):
        self.maze = maze
        self.x = x
        self.y = y
        self.cx = x + 0.5
        self.cy = y + 0.5
        self.terrain = terrain
        self.all_entities = set()
        self.active_entities = set()

    def __info__(self):
        terrain = "<no terrain>" if self.terrain is None else self.terrain.__name__
        return ("%s@(%d, %d): %d entities [%d active]" %
                (terrain, self.x, self.y,
                 len(self.all_entities),
                 len(self.active_entities)))

    @property
    def time(self):
        return self.maze.time

    @property
    def coords(self):
        return (self.x, self.y)

    @property
    def center(self):
        return (self.cx, self.cy)

    @Many(complement="tile")
    def entities(self):
        return self.all_entities

    @entities.adder
    def entities(self, entity):
        self.all_entities.add(entity)
        self.maze.all_entities.add(entity)
        if entity.active:
            self.active_entities.add(entity)
            self.maze.active_entities.add(entity)

    @entities.remover
    def entities(self, entity):
        self.all_entities.remove(entity)
        self.maze.all_entities.remove(entity)
        if entity.active:
            self.active_entities.remove(entity)
            self.maze.active_entities.remove(entity)

    def neighbor_tile(self, direction, distance=1):
        return self.maze.neighbor_tile(self.x, self.y, direction, distance)

    def neighbor_tiles(self, distance=1):
        return self.maze.neighbor_tiles(self.x, self.y, distance)
